package web.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
//import web.Annotation.readbody.XssHttpServletRequestWrapper;
import web.common.Result;
import web.entity.Security_UserDetail;
import web.entity.UserDo;
import web.entity.admin.log.LoginDo;
import web.mapper.CommonMapper;
import web.mapper.LogMysqlMapper;
import web.service.CommonService;
import web.service.Security_LoginService;
import web.service.UserService;
import web.utils.AesEncryptUtil;
import web.utils.JwtUtil;
import web.utils.RandomUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class Security_LoginServiceImpl implements Security_LoginService {

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    LogMysqlMapper logMysqlMapper;

    @Autowired
    @Qualifier("redisTemplate_15_verfiyCode") // 指定注入redisTemplate15
    private RedisTemplate redisTemplate_15_verfiyCode;

    @Autowired
    CommonMapper commonMapper;
    @Autowired
    UserDetailsService userDetailsService;

    @Value("${tokenExpire.redis_hours}")
    private Integer redis_hours;

    @Autowired
    UserService userService;

    @Override
    public Result login(UserDo userDo) {
        System.out.println("login service IMPL");
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        boolean b = checkCaptcha(req);
//        if (!b){
//            return Result.fail("验证码错误");
//        }
        String nos=req.getHeader("nos");
        String getPassword="";
        String account="";

        if(StringUtil.isNotEmpty(nos)&&nos.equals("1")){
             getPassword = (userDo.getPassword());
             account = (userDo.getAccount());
        }
        else {
             getPassword = AesEncryptUtil.desEncrypt(userDo.getPassword());
             account = AesEncryptUtil.desEncrypt(userDo.getAccount());
        }
        /*接受前端参数,封装成特定对象*/
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(account,getPassword);
        /*查询数据库,验证账号密码*/
        Authentication authenticate = null;
        Security_UserDetail security_userDetail = null;
        String user_account = null;
        String user_name = null;
        String user_type = null;
        int  deptid=0;
        try {
            authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        }catch (Exception e){
            e.printStackTrace();
        }

        LoginDo loginDo = new LoginDo();
        if (authenticate == null){
            loginDo.setUser_id(userDo.getAccount());
            loginDo.setUser_name("anonymous");
            loginDo.setAccessed("0");
        }else {
            security_userDetail = (Security_UserDetail)authenticate.getPrincipal();
            user_account = security_userDetail.getUserDo().getAccount();
            user_name = security_userDetail.getUserDo().getUser_name();
            user_type = security_userDetail.getUserDo().getUser_type();
            deptid=security_userDetail.getUserDo().getDep_id();
            loginDo.setUser_id(user_account);
            loginDo.setUser_name(user_name);
            loginDo.setDepid(deptid);
            loginDo.setAccessed("1");
        }

        loginDo.setIp(req.getRemoteAddr());
        loginDo.setCreate_time(RandomUtils.nowStr(""));


        logMysqlMapper.insertLoginLog(loginDo);

        if (authenticate == null){
            return Result.fail("用户名或密码错误");
        }else {
            /*用户信息存入redis*/
            try {
                ValueOperations valueOperations = redisTemplate.opsForValue();
                valueOperations.set(user_account, security_userDetail,redis_hours, TimeUnit.HOURS);
//            redisCache.setTTL(redisPrefix + id, ss);
            } catch (Exception e) {
                e.printStackTrace();
//            redis插入值失败: ①redis服务未启用
                return Result.fail("redis error");
//            return new ResponseResult(500, "cach error");
            }

            /*根据用户account生成token*/
            String jwt = JwtUtil.createJWT(user_account);
            HashMap<String, String> tokenMap = new HashMap<>();
            tokenMap.put("mydx_token", jwt);
            tokenMap.put("user_name", user_name);
            tokenMap.put("user_type", user_type);
            tokenMap.put("user_type", getUserType(security_userDetail.getUserDo()));
            tokenMap.put("depid",String.valueOf(deptid));
            System.out.println("service结束");
            return Result.succ(tokenMap);
        }
    }


    @Override
    public Result Phonelogin(String phone) {
        System.out.println("phonelogin service IMPL");
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String account=phone;
        /*查询数据库,验证账号密码*/
        Authentication authenticate = null;
        Security_UserDetail security_userDetail = null;
        String user_account = null;
        String user_name = null;
        String user_type = null;
        int  deptid=0;
        try {
            security_userDetail=(Security_UserDetail) userDetailsService.loadUserByUsername(phone);
        }catch (Exception e){
            e.printStackTrace();
        }
        LoginDo loginDo = new LoginDo();
        if (security_userDetail == null){
            loginDo.setUser_id(phone);
            loginDo.setUser_name("anonymous");
            loginDo.setAccessed("0");
        }else {
            user_account = security_userDetail.getUserDo().getAccount();
            user_name = security_userDetail.getUserDo().getUser_name();
            user_type = security_userDetail.getUserDo().getUser_type();
            deptid=security_userDetail.getUserDo().getDep_id();
            loginDo.setUser_id(user_account);
            loginDo.setUser_name(user_name);
            loginDo.setDepid(deptid);
            loginDo.setAccessed("1");
        }

        loginDo.setIp(req.getRemoteAddr());
        loginDo.setCreate_time(RandomUtils.nowStr(""));


        logMysqlMapper.insertLoginLog(loginDo);

        if (security_userDetail == null){
            return Result.fail("用户名或密码错误");
        }else {
            /*用户信息存入redis*/
            try {
                ValueOperations valueOperations = redisTemplate.opsForValue();
                valueOperations.set(user_account, security_userDetail,redis_hours, TimeUnit.HOURS);
//            redisCache.setTTL(redisPrefix + id, ss);
            } catch (Exception e) {
                e.printStackTrace();
//            redis插入值失败: ①redis服务未启用
                return Result.fail("redis error");
//            return new ResponseResult(500, "cach error");
            }

            /*根据用户account生成token*/
            String jwt = JwtUtil.createJWT(user_account);
            HashMap<String, String> tokenMap = new HashMap<>();
            tokenMap.put("mydx_token", jwt);
            tokenMap.put("user_name", user_name);
            tokenMap.put("user_type", user_type);
            tokenMap.put("user_type", getUserType(security_userDetail.getUserDo()));
            tokenMap.put("depid",String.valueOf(deptid));
            System.out.println("phoneloginservice结束");
            return Result.succ(tokenMap);
        }
    }

    /**
     * 不再使用sys_user的user_type字段判断是否显示跳转后台按钮
     * 而是从菜单表中读取当前用户是否有任何后台菜单
     * 有：可跳转 user_type = 0
     * 无：不可跳转 user_type = 1
     * @param userDo
     * @return
     */
    String getUserType(UserDo userDo){
        String id = userDo.getId().toString();
        List<HashMap<String,Object>> menuList = userService.getMenuListById (id);
        if (menuList.size()>0){
            return "0";
        }
        return "1";
    }

}
